package com.bt.mes.query.provider.service;


import static com.def.GenericDef.E_READ_NOT_FOUND;
import static com.def.GenericDef.E_RET_PRD_INFO;
import static com.def.GenericDef.E_RET_PRD_INFO_SHTC;
import static com.def.GenericDef.E_XPINQBOX_INVALID_INPUT;
import static com.def.GenericDef.E_XPINQBOX_READ_SHT_ERROR;
import static com.def.GenericDef.RETURN_CODE_OK;
import static com.def.GenericDef.RETURN_CODE_SET_ERROR;
import static com.def.GenericDef.RETURN_CODE_UNKNOWN;
import static com.def.GenericDef.RETURN_MESG_OK;
import static com.def.GenericDef.TRX_OUT;
import static com.def.GenericDef._NORMAL;
import static com.def.GenericDef._YES;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.bt.mes.common.dao.IBisDataDao;
import com.bt.mes.common.dao.IBisMdlDefDao;
import com.bt.mes.common.dao.IBisOpeDao;
import com.bt.mes.common.dao.IRetPrdInfoDao;
import com.bt.mes.common.dao.IRetPrdInfoShtcDao;
import com.bt.mes.common.dao.IRetWODao;
import com.bt.mes.common.util.JacksonUtil;
import com.bt.mes.common.util.MqOpe;
import com.bt.mes.common.util.Util;
import com.bt.mes.query.api.service.IXpinqshtService;
import com.bt.mes.query.provider.tx.Xpinqsht.XpinqshtI;
import com.bt.mes.query.provider.tx.Xpinqsht.XpinqshtO;
import com.bt.mes.query.provider.tx.Xpinqsht.XpinqshtOA;
import com.bt.mes.query.provider.tx.Xpinqsht.XpinqshtOA2;
import com.bt.mes.query.provider.tx.Xpinqsht.XpinqshtOA3;
import com.bt.table.ppt.Bis_data;
import com.bt.table.ppt.Bis_mdl_def;
import com.bt.table.ppt.Bis_ope;
import com.bt.table.ppt.Bis_opeId;
import com.bt.table.ppt.Ret_prd_info;
import com.bt.table.ppt.Ret_prd_info_shtc;
import com.bt.table.ppt.Ret_wo;


@Service("xpinqshtService")
public class XpinqshtService implements IXpinqshtService{
	private static Logger logger = Logger.getLogger(XpinqshtService.class);
	private static String TX_NAME = "XPINQSHT";

	private XpinqshtI inTrx;
	private XpinqshtO outTrx;

	@Autowired
	private IRetPrdInfoDao retPrdInfoDao;
	@Autowired
	private IRetWODao retWoDao;
	@Autowired
	private IBisOpeDao bisOpeDao;
	@Autowired
	private IBisDataDao bisDataDao;
	@Autowired
	private IBisMdlDefDao bisMdlDefDao;
	@Autowired
	private IRetPrdInfoShtcDao retPrdInfoShtcDao;
	
	private String gszMsgBuf = "";

	public String subMainProc(String strInMsg) {
		long rtnCode = _NORMAL;
		gszMsgBuf = "";
		String outMsg = "";
		inTrx = new XpinqshtI();
		outTrx = new XpinqshtO();
		outTrx.setTrx_id(TX_NAME);
		outTrx.setRtn_code(String.valueOf(RETURN_CODE_SET_ERROR));
		outTrx.setType_id(TRX_OUT);


		try {
			inTrx = JacksonUtil.fromJson(strInMsg, XpinqshtI.class);
			logger.info("InTrx is " + strInMsg);

			rtnCode = subMainProc2(inTrx.getAction_flg().toCharArray()[0]);
			if (rtnCode != _NORMAL) {
				outTrx.setRtn_code(String.valueOf(rtnCode));
				outTrx.setRtn_mesg(gszMsgBuf);
				TransactionAspectSupport.currentTransactionStatus()
						.setRollbackOnly();
			} else {
				outTrx.setRtn_code(String.valueOf(RETURN_CODE_OK));
				outTrx.setRtn_mesg(RETURN_MESG_OK);
				retPrdInfoDao.flushCurSession();
			}
		} catch (Exception ex) {
			outTrx.setRtn_mesg(ex.toString());
			outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
			logger.error(Util.stackTraceToString(ex));
			TransactionAspectSupport.currentTransactionStatus()
					.setRollbackOnly();
		} finally {
			outMsg = JacksonUtil.toJsonString(outTrx);
		}
		return outMsg;
	}

	private long subMainProc2(char actionType) {
		long rtnCode = _NORMAL;

		switch (actionType) {
		case 'Q': {
			rtnCode = getPrdInfo();
			break;
		}
		case 'C': {
			rtnCode = queryByCondition();
			break;
		}
		case 'T': {
			rtnCode = getPrdTableRecord();
			break;
		}
		case 'S': {
			rtnCode = getPrdByTimeAndTool();
			break;
		}
		case 'I': {
			rtnCode = getPrdWipInfo();
			break;
		}
		case 'O': {
			rtnCode = getPrdShtcInfo();
			break;
		}
		case 'F':{
			rtnCode = getByFabSnProc();
			break;
		}
		default: {
			gszMsgBuf = "Invalide type input: [" + actionType + "]";
			return E_XPINQBOX_INVALID_INPUT;
		}
		}
		return rtnCode;
	}

	private long getByFabSnProc() {
		String fabSn = inTrx.getFab_sn();
		String hql = "FROM Ret_prd_info where fab_sn = ?";
		List<Ret_prd_info> retPrdInfoList = retPrdInfoDao.list(hql, fabSn);
		if(retPrdInfoList.size()>1){
			outTrx.setHas_more_flg("Y");
		}else{
			outTrx.setHas_more_flg("N");
		}
		List<XpinqshtOA3> oary3List = new ArrayList<XpinqshtOA3>();
		for(Ret_prd_info retPrdInfo : retPrdInfoList){
			XpinqshtOA3 oary3 = new XpinqshtOA3();
			oary3.setFab_sn(retPrdInfo.getFab_sn());
			oary3.setPrd_seq_id(retPrdInfo.getPrd_seq_id());
			oary3.setWo_id(retPrdInfo.getWo_id_fk());
			oary3List.add(oary3);
		}
		outTrx.setOary3(oary3List);
		outTrx.setOary3_cnt(oary3List.size());
		outTrx.setSht_cnt(oary3List.size());
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		return _NORMAL;
	}

	private long queryByCondition() {
		long lRc = _NORMAL;
		// Get prd list
		List<Ret_prd_info> ret_prd_infoList = new ArrayList<Ret_prd_info>();
		String sql = "FROM Ret_prd_info WHERE 1=1 ";
		if (!Util.isSpaceCheck(inTrx.getPrd_stat())) {
			sql = sql + " AND prd_stat='" + inTrx.getPrd_stat() + "'";
		} else if (!Util.isSpaceCheck(inTrx.getPrd_stats())) {
			sql = sql + " AND prd_stat IN(" + inTrx.getPrd_stats() + ")";
		}
		if (!Util.isSpaceCheck(inTrx.getOpe_id())) {
			sql = sql + " AND cr_ope_id_fk='" + inTrx.getOpe_id() + "'";
		}
		if (!Util.isSpaceCheck(inTrx.getWo_id())) {
			sql = sql + " AND wo_id_fk='" + inTrx.getWo_id() + "'";
		}
		if (!Util.isSpaceCheck(inTrx.getLot_id())) {
			sql += " AND lot_id = '"+inTrx.getLot_id()+"'";
		}		
		if (!Util.isSpaceCheck(inTrx.getSpace_box_id())
				&& _YES.equals(inTrx.getSpace_box_id())) {
			sql = sql + " AND box_id_fk=' '";
		} else if (!Util.isSpaceCheck(inTrx.getBox_id())) {
			sql = sql + " AND box_id_fk='" + inTrx.getBox_id() + "'";
		}
		
		if (!Util.isSpaceCheck(inTrx.getFab_sn())) {
			sql += " AND fab_sn like '%"+inTrx.getFab_sn()+"%'";
		}

		if(!Util.isSpaceCheck(inTrx.getMtrl_box_id())){
			sql += " AND mtrl_box_id_fk = '" + inTrx.getMtrl_box_id() + "'";
		}
		ret_prd_infoList = retPrdInfoDao.find(sql);
		if (ret_prd_infoList.isEmpty()) {
			outTrx.setTbl_cnt(0);
		} else {
			outTrx.setTbl_cnt(ret_prd_infoList.size());
			outTrx.setOary_table(ret_prd_infoList);
		}

		return _NORMAL;
	}

	private long getPrdWipInfo() {

		long lRc = _NORMAL;
		String prd_seq_id = inTrx.getPrd_seq_id();
		Ret_prd_info ret_prd_info = retPrdInfoDao.get(prd_seq_id);
		if (ret_prd_info == null) {
			return _NORMAL;
		}
		String prd_stat = ret_prd_info.getPrd_stat();
		XpinqshtOA2 oary2 = new XpinqshtOA2();
		List<XpinqshtOA2> oary2List = new ArrayList<XpinqshtOA2>();
		oary2.setLot_id(ret_prd_info.getLot_id());
		oary2.setPrd_stat(ret_prd_info.getPrd_stat());
		oary2.setWo_id_fk(ret_prd_info.getWo_id_fk());
		if(null != ret_prd_info.getWo_id_fk()){
			Ret_wo retwo = retWoDao.get(ret_prd_info.getWo_id_fk());
			if(null != retwo){
				oary2.setMtrl_prod_id_fk(retwo.getMtrl_prod_id_fk());
			    oary2.setTh_mdl_id_fk(retwo.getTh_mdl_id_fk());
			    oary2.setFm_mdl_id_fk(retwo.getFm_mdl_id_fk());
			    oary2.setCut_mdl_id_fk(retwo.getCut_mdl_id_fk());
			}
		}
		oary2.setSo_id_fk(ret_prd_info.getSo_id_fk());
		oary2.setEvt_cate(ret_prd_info.getEvt_cate());
		oary2.setBox_id_fk(ret_prd_info.getBox_id_fk());
		oary2.setSlot_no(ret_prd_info.getSlot_no());
		//oary2.setMdl_id_fk(ret_prd_info.getMdl_id_fk());

		oary2.setAc_recipe_id(ret_prd_info.getAc_recipe_id());
		oary2.setDs_recipe_id(ret_prd_info.getDs_recipe_id());
		oary2.setPrd_qty(ret_prd_info.getPrd_qty());
		oary2.setTool_port_id_fk(ret_prd_info.getTool_port_id_fk());
		
		oary2.setFab_sn(ret_prd_info.getFab_sn());

		if (("INPR").equals(prd_stat)) {
			oary2.setOpe_no_fk(ret_prd_info.getCr_ope_no_fk());
			oary2.setOpe_id_fk(ret_prd_info.getCr_ope_id_fk());
			oary2.setOpe_ver_fk(ret_prd_info.getCr_ope_ver_fk());
			oary2.setToolg_id_fk(ret_prd_info.getCr_toolg_id_fk());
			// oary2.setTool_id_fk(ret_prd_info.getCr_tool_id_fk());
			oary2.setPath_id_fk(ret_prd_info.getCr_path_id_fk());
			oary2.setPath_ver_fk(ret_prd_info.getCr_path_ver_fk());
			oary2.setProc_id_fk(ret_prd_info.getCr_proc_id_fk());
		} else {
			oary2.setOpe_no_fk(ret_prd_info.getNx_ope_no_fk());
			oary2.setOpe_id_fk(ret_prd_info.getNx_ope_id_fk());
			oary2.setOpe_ver_fk(ret_prd_info.getNx_ope_ver_fk());
			oary2.setToolg_id_fk(ret_prd_info.getNx_toolg_id_fk());
			// oary2.setTool_id_fk(ret_prd_info.getNx_tool_id_fk());
			oary2.setPath_id_fk(ret_prd_info.getNx_path_id_fk());
			oary2.setPath_ver_fk(ret_prd_info.getNx_path_ver_fk());
			oary2.setProc_id_fk(ret_prd_info.getNx_proc_id_fk());
		}
		// TODO:获取站点信息中文说明
		Bis_opeId opeId = new Bis_opeId();
		opeId.setOpe_id(oary2.getOpe_id_fk());
		opeId.setOpe_ver(oary2.getOpe_ver_fk());
		Bis_ope bis_ope = bisOpeDao.get(opeId);
		if (bis_ope != null) {
			oary2.setOpe_no_dsc(bis_ope.getOpe_dsc());
		}

		// TODO:获取宣告类型的中文说明.
		String sql = "From Bis_data where data_cate='EVCT'and data_id='"
				+ oary2.getEvt_cate() + "'";
		List<Bis_data> bis_data_list = bisDataDao.find(sql);
		if (bis_data_list.size() != 0) {
			oary2.setEvt_cate_dsc(bis_data_list.get(0).getData_desc());
		} else {
			oary2.setEvt_cate_dsc(oary2.getEvt_cate());
		}
		// TODO:获取产品规格
		Bis_mdl_def bis_mdl_def = bisMdlDefDao.get(ret_prd_info.getMdl_id_fk());
		if (bis_mdl_def != null) {
			oary2.setMdl_typ_fk(bis_mdl_def.getMdl_dsc());
		}
		oary2.setTool_id_fk(ret_prd_info.getCr_tool_id_fk());
		oary2.setEvt_usr(ret_prd_info.getEvt_usr());
		oary2.setSht_ope_msg(ret_prd_info.getSht_ope_msg());
		oary2.setPrty(ret_prd_info.getPrty());
		oary2.setMdl_cate_fk(ret_prd_info.getMdl_cate_fk());
		// oary2.setMdl_typ_fk(ret_prd_info.getMdl_typ_fk());
		oary2.setGroup_id(ret_prd_info.getGroup_id());
		oary2.setPrd_grade(ret_prd_info.getPrd_grade());
		oary2List.add(oary2);
		outTrx.setOary2(oary2List);
		return _NORMAL;
	}

	private long getPrdTableRecord() {
		long lRc = _NORMAL;
		String prd_seq_id = inTrx.getPrd_seq_id();
		Ret_prd_info ret_prd_info = retPrdInfoDao.get(prd_seq_id);
		outTrx.setPrd_tbl(ret_prd_info);

		return _NORMAL;
	}

	/**
	 * Only query box info
	 * 
	 * @return
	 */
	private long getPrdInfo() {
		long lRc = _NORMAL;
		String prd_seq_id = inTrx.getPrd_seq_id();
		if(StringUtils.isEmpty(prd_seq_id)){
			gszMsgBuf = "产品ID不能为空!";
			return E_READ_NOT_FOUND + E_RET_PRD_INFO;
		}
		Ret_prd_info ret_prd_info = retPrdInfoDao.get(prd_seq_id);
		if (ret_prd_info != null) {

			outTrx.setPrd_seq_id(ret_prd_info.getPrd_seq_id());
			outTrx.setPrd_qty(ret_prd_info.getPrd_qty());
			outTrx.setBox_id_fk(ret_prd_info.getBox_id_fk());
			outTrx.setPrd_stat(ret_prd_info.getPrd_stat());
			outTrx.setMdl_id_fk(ret_prd_info.getMdl_id_fk());
			outTrx.setCr_ope_id_fk(ret_prd_info.getCr_ope_id_fk());
			outTrx.setCr_ope_no_fk(ret_prd_info.getCr_ope_no_fk());
			outTrx.setCr_ope_ver_fk(ret_prd_info.getCr_ope_ver_fk());
			outTrx.setCr_path_id_fk(ret_prd_info.getCr_path_id_fk());
			outTrx.setCr_path_ver_fk(ret_prd_info.getCr_path_ver_fk());
			outTrx.setCr_proc_id_fk(ret_prd_info.getCr_proc_id_fk());
			outTrx.setCr_tool_id_fk(ret_prd_info.getCr_tool_id_fk());
			outTrx.setWo_id_fk(ret_prd_info.getWo_id_fk());
			outTrx.setFab_sn(ret_prd_info.getFab_sn());
			
			Ret_wo ret_so = retWoDao.get(ret_prd_info.getSo_id_fk());
			if (ret_so != null) {
				if (ret_so.getFrom_thickness() != null) {
					outTrx.setFrom_thickness(ret_so.getFrom_thickness()
							.toString());
				}
				if (ret_so.getTo_thickness() != null) {
					outTrx.setTo_thickness(ret_so.getTo_thickness().toString());
				}

			}

		}
		return lRc;
	}

	private long getPrdByTimeAndTool() {
		long lRc = _NORMAL;
		String fileLastModifyTimestamp = inTrx.getStrTimeStamp();
		StringBuffer buffer = new StringBuffer();
		// fileLastModifyTimestamp = "2013-09-10 14:55:40";
		String toolID = inTrx.getTool_id();
		List<Ret_prd_info> retPrdInfoList = new ArrayList<Ret_prd_info>();
		List<XpinqshtOA> oaryList = new ArrayList<XpinqshtOA>();
		Session session = null;
		try {
			String sql = "SELECT * FROM RET_PRD_INFO where evt_timestamp between"
					+ " DATE_ADD('"
					+ fileLastModifyTimestamp
					+ "',INTERVAL -3 SECOND) AND"
					+ " DATE_ADD('"
					+ fileLastModifyTimestamp
					+ "',INTERVAL 3 SECOND) AND"
					+ " cr_tool_id_fk = '" + toolID + "'";
			buffer.append("SELECT * FROM RET_PRD_INFO where ")
					.append(" prd_stat = 'INPR'")
					.append(" AND cr_tool_id_fk='").append(toolID).append("'")
					.append(" AND evt_timestamp between").append(" DATE_ADD('")
					.append(fileLastModifyTimestamp)
					.append("',INTERVAL -300 SECOND)").append(" AND '")
					.append(fileLastModifyTimestamp).append("'")
					.append(" ORDER BY evt_timestamp desc");
			// session = retPrdInfoDao.getCrSession();
			// Query query = session.createSQLQuery(buffer.toString());
			// retPrdInfoList = query.list();
			retPrdInfoList = retPrdInfoDao.findBySQL(buffer.toString(),
					Ret_prd_info.class);
		} catch (Exception ex) {
			lRc = E_XPINQBOX_READ_SHT_ERROR;
			logger.error("read RET_PRD_INFO ERROR:" + ex.toString());
			logger.error(Util.stackTraceToString(ex));
		}

		for (Ret_prd_info ret_prd_info : retPrdInfoList) {
			XpinqshtOA oary = new XpinqshtOA();
			oary.setPrd_seq_id(ret_prd_info.getPrd_seq_id());
			oary.setFab_sn(ret_prd_info.getFab_sn());
			oary.setCr_ope_id(ret_prd_info.getCr_ope_id_fk());
			oary.setCr_ope_no(ret_prd_info.getCr_ope_no_fk());
			oary.setCr_ope_ver(ret_prd_info.getCr_ope_ver_fk());
			oary.setCr_path_id(ret_prd_info.getCr_path_id_fk());
			oary.setCr_path_ver(ret_prd_info.getCr_path_ver_fk());
			oary.setCr_proc_id_fk(ret_prd_info.getCr_proc_id_fk());
			oaryList.add(oary);
		}
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		outTrx.setOary(oaryList);
		outTrx.setSht_cnt(oaryList.size());
		return lRc;

	}
	/**
	 * 查询出货的产品信息
	 */
	private long getPrdShtcInfo(){
		long lRc = _NORMAL;
		List<XpinqshtOA2> oary2List = new ArrayList<XpinqshtOA2>();
		List<Ret_prd_info_shtc> prdInfoSthcList = new ArrayList<Ret_prd_info_shtc>();
		String sql = "FROM Ret_prd_info_shtc WHERE box_id_fk='" 
			+ inTrx.getBox_id() +"'";
		prdInfoSthcList = retPrdInfoShtcDao.find(sql);
		if(prdInfoSthcList.isEmpty()){
			gszMsgBuf = "找不到箱子[" + inTrx.getBox_id() + "]的出货信息!";
			return E_READ_NOT_FOUND + E_RET_PRD_INFO_SHTC;
		}
		
		for(int i=0; i<prdInfoSthcList.size(); i++){
			XpinqshtOA2 oary2 = new XpinqshtOA2();
			oary2.setPrd_seq_id(prdInfoSthcList.get(i).getPrd_seq_id());
			oary2.setFab_sn(prdInfoSthcList.get(i).getFab_sn());
			oary2.setBox_id_fk(prdInfoSthcList.get(i).getBox_id_fk());
			oary2.setSlot_no(prdInfoSthcList.get(i).getSlot_no());
			oary2.setWo_id_fk(prdInfoSthcList.get(i).getWo_id_fk());
			oary2.setMdl_id_fk(prdInfoSthcList.get(i).getMdl_id_fk());
			oary2.setLot_id(prdInfoSthcList.get(i).getLot_id());
			oary2.setShipping_timestamp(prdInfoSthcList.get(i).getShipping_timestamp());
			oary2List.add(oary2);
		}
		outTrx.setOary2(oary2List);
		return lRc;
	}
}
